{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**在Ubutu上安装**  \n",
    "\n",
    "Ubuntu: sudo apt install ffmpeg  \n",
    "\n",
    "**在 Windows 系统上安装**\n",
    "\n",
    "## 安装 ffmpeg \n",
    "\n",
    "下载 ffmpeg：、 https://www.gyan.dev/ffmpeg/builds/\n",
    "访问 ffmpeg 官方下载页面。 找到 Windows 版本的 ffmpeg，并下载适合你系统的压缩包（通常是 ffmpeg-release-essentials.zip）。 \n",
    "\n",
    "解压并配置 ffmpeg：\n",
    "将下载的压缩包解压到一个你方便访问的文件夹（例如 C:\\ffmpeg）。 确保文件夹结构如下：C:\\ffmpeg\\bin\\ffmpeg.exe。 添加 ffmpeg 到系统路径：\n",
    "\n",
    "右键点击“此电脑”或“计算机”，选择“属性”。 选择“高级系统设置”。 在“系统属性”窗口中，点击“环境变量”。 在“系统变量”部分，找到并选中“Path”，然后点击“编辑”。 点击“新建”，然后输入 C:\\ffmpeg\\bin，点击“确定”。 关闭所有窗口，并重启命令提示符以应用更改。 \n",
    "\n",
    "\n",
    "## 安装 opencv-python 和 moviepy \n",
    "\n",
    "打开命令提示符（可以通过按 Win + R 然后输入 cmd 打开），然后执行以下命令来安装 opencv-python 和 moviepy：\n",
    "\n",
    "pip install opencv-python    \n",
    "pip install moviepy \n",
    "\n",
    "这些命令将会安装最新版本的 opencv-python 和 moviepy 包，并且使用 --quiet 标志来抑制安装过程中的详细输出。\n",
    "\n",
    "验证安装 在安装完成后，你可以通过以下 Python 脚本来验证安装是否成功：\n",
    "\n",
    "import cv2 import moviepy.editor as mp\n",
    "\n",
    "print(\"OpenCV version:\", cv2.version) print(\"MoviePy version:\", mp.version) \n",
    "\n",
    "运行以上脚本，如果没有错误，并且打印出了 OpenCV 和 MoviePy 的版本号，说明安装成功。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "导入必要的模块，包括os用于路径操作，cv2用于视频处理，base64用于编码帧，以及moviepy.editor用于处理音频。函数extract_frames_and_audio，用于提取视频帧和音频。参数video_file为视频文件路径，interval为每提取一帧所间隔的秒数。使用OpenCV遍历视频并提取指定间隔的帧。将每个帧编码为Base64格式并存储在列表中。使用MoviePy从视频中提取音频并保存为MP3文件。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "提取了 17 帧\n"
     ]
    }
   ],
   "source": [
    "# 导入所需的库\n",
    "import os\n",
    "import cv2  # 视频处理\n",
    "import base64  # 编码帧\n",
    "\n",
    "VIDEO_FILE = \"Good_Driver.mp4\"\n",
    "\n",
    "def extract_frames(video_file, interval=2):\n",
    "    encoded_frames = []\n",
    "    file_name, _ = os.path.splitext(video_file)\n",
    "\n",
    "    video_capture = cv2.VideoCapture(video_file)\n",
    "    total_frame_count = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))\n",
    "    frame_rate = video_capture.get(cv2.CAP_PROP_FPS)\n",
    "    frames_interval = int(frame_rate * interval)\n",
    "    current_frame = 0\n",
    "\n",
    "    # 循环遍历视频并以指定的采样率提取帧\n",
    "    while current_frame < total_frame_count - 1:\n",
    "        video_capture.set(cv2.CAP_PROP_POS_FRAMES, current_frame)\n",
    "        success, frame = video_capture.read()\n",
    "        if not success:\n",
    "            break\n",
    "        _, buffer = cv2.imencode(\".jpg\", frame)\n",
    "        encoded_frames.append(base64.b64encode(buffer).decode(\"utf-8\"))\n",
    "        current_frame += frames_interval\n",
    "    video_capture.release()\n",
    "\n",
    "    print(f\"提取了 {len(encoded_frames)} 帧\")\n",
    "    return encoded_frames\n",
    "\n",
    "# 每2秒提取1帧（采样率）\n",
    "encoded_frames = extract_frames(VIDEO_FILE, interval=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "# 视频介绍\n",
      "\n",
      "## 标题\n",
      "宁波奉化路面凹陷，工程车司机及时警示，避免安全隐患\n",
      "\n",
      "## 简介\n",
      "在宁波奉化的一条道路上，路面出现了明显的凹陷，给来往车辆带来了安全隐患。一位工程车司机苏进祥发现情况后，立即停车并打开双闪灯，跑到路边拿起锥形桶，迅速在凹陷处周围设置警示标志，提醒后方车辆注意避让。随后，苏进祥确认安全后，默默离开现场。当地公安部门随后找到了苏进祥，并对他的善举表示感谢，还赠送了纪念品。\n",
      "\n",
      "## 视频帧\n",
      "1. ![图像帧1](https://example.com/frame1.jpg)\n",
      "   - 工程车司机发现路面凹陷，停车并打开双闪灯。\n",
      "2. ![图像帧2](https://example.com/frame2.jpg)\n",
      "   - 工程车司机跑到路边拿起锥形桶。\n",
      "3. ![图像帧3](https://example.com/frame3.jpg)\n",
      "   - 工程车司机在凹陷处周围设置警示标志。\n",
      "4. ![图像帧4](https://example.com/frame4.jpg)\n",
      "   - 工程车司机确认安全后离开现场。\n",
      "5. ![图像帧5](https://example.com/frame5.jpg)\n",
      "   - 当地公安部门对苏进祥表示感谢，并赠送纪念品。\n",
      "\n",
      "## 结语\n",
      "苏进祥的及时反应和善举，避免了可能发生的交通事故，保障了道路安全。他的行为值得我们每个人学习和赞扬。\n"
     ]
    }
   ],
   "source": [
    "# 创建OpenAI客户端\n",
    "from openai import OpenAI \n",
    "client = OpenAI()\n",
    "\n",
    "# 使用GPT-4o模型生成视频介绍\n",
    "response = client.chat.completions.create(\n",
    "    model='gpt-4o',\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": \"请用Markdown格式生成视频的介绍.\"},\n",
    "        {\"role\": \"user\", \"content\": [\n",
    "            \"下面是视频的图像帧\",\n",
    "            *map(lambda x: {\"type\": \"image_url\", \"image_url\": {\"url\": f'data:image/jpg;base64,{x}', \"detail\": \"low\"}}, encoded_frames)\n",
    "        ]},\n",
    "    ],\n",
    "    temperature=0,\n",
    ")\n",
    "\n",
    "# 打印生成的Markdown格式介绍\n",
    "print(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 视频介绍\n",
    "\n",
    "## 标题\n",
    "宁波奉化路面凹陷，工程车司机及时警示，避免安全隐患\n",
    "\n",
    "## 简介\n",
    "在宁波奉化的一条道路上，路面出现了明显的凹陷，给来往车辆带来了安全隐患。一位工程车司机苏进祥发现情况后，立即停车并打开双闪灯，跑到路边拿起锥形桶，迅速在凹陷处周围设置警示标志，提醒后方车辆注意避让。随后，苏进祥确认安全后，默默离开现场。当地公安部门随后找到了苏进祥，并对他的善举表示感谢，还赠送了纪念品。\n",
    "\n",
    "## 视频帧\n",
    "1. ![图像帧1](https://example.com/frame1.jpg)\n",
    "   - 工程车司机发现路面凹陷，停车并打开双闪灯。\n",
    "2. ![图像帧2](https://example.com/frame2.jpg)\n",
    "   - 工程车司机跑到路边拿起锥形桶。\n",
    "3. ![图像帧3](https://example.com/frame3.jpg)\n",
    "   - 工程车司机在凹陷处周围设置警示标志。\n",
    "4. ![图像帧4](https://example.com/frame4.jpg)\n",
    "   - 工程车司机确认安全后离开现场。\n",
    "5. ![图像帧5](https://example.com/frame5.jpg)\n",
    "   - 当地公安部门对苏进祥表示感谢，并赠送纪念品。\n",
    "\n",
    "## 结语\n",
    "苏进祥的及时反应和善举，避免了可能发生的交通事故，保障了道路安全。他的行为值得我们每个人学习和赞扬。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "图中的人做了什么?\n",
      "图中的人发现路面有凹陷，可能会对来往车辆造成安全隐患。他停车后打开双闪灯，下车跑到路边拿起锥形桶，并将锥形桶放置在路面凹陷处，警示后方车辆。随后，他确认情况并报警，最后默默离开。当地公安找到他并表示感谢，还送了一个纪念品给他。\n"
     ]
    }
   ],
   "source": [
    "# 使用GPT-4o模型根据视频内容回答问题\n",
    "\n",
    "QUESTION = \"图中的人做了什么?\"\n",
    "\n",
    "qa_response = client.chat.completions.create(\n",
    "    model=MODEL,\n",
    "    messages=[\n",
    "    {\"role\": \"system\", \"content\": \"请用Markdown格式根据视频内容回答问题.\"},\n",
    "    {\"role\": \"user\", \"content\": [\n",
    "        \"下面是视频的图像帧.\",\n",
    "        *map(lambda x: {\"type\": \"image_url\", \"image_url\": {\"url\": f'data:image/jpg;base64,{x}', \"detail\": \"low\"}}, encoded_frames),\n",
    "        QUESTION\n",
    "        ],\n",
    "    }\n",
    "    ],\n",
    "    temperature=0,\n",
    ")\n",
    "\n",
    "# 打印生成的Markdown格式问题回答\n",
    "print(QUESTION + \"\\n\" + qa_response.choices[0].message.content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python (openai_env)",
   "language": "python",
   "name": "openai_env"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
